#include <cstring>
#include <iostream>
#include <vector>
using namespace std;

#define int long long

const int MAXN = 100010; // 根据题目要求调整大小

int n, m;
int a[MAXN];
int d[MAXN * 4];
int b[MAXN * 4]; // 懒标记数组

// 上推更新节点值
void push_up(int p)
{
    d[p] = d[p << 1] + d[(p << 1) | 1];
}

// 下推懒标记
void push_down(int s, int t, int p)
{
    if (b[p] == 0)
        return;
    int m = s + ((t - s) >> 1);

    // 更新左子节点
    d[p << 1] += b[p] * (m - s + 1);
    b[p << 1] += b[p];

    // 更新右子节点
    d[(p << 1) | 1] += b[p] * (t - m);
    b[(p << 1) | 1] += b[p];

    // 清除当前节点标记
    b[p] = 0;
}

// 构建线段树
void build(int l, int r, int p)
{
    if (l == r) {
        d[p] = a[l];
        return;
    }
    int m = l + ((r - l) >> 1);
    build(l, m, p << 1);
    build(m + 1, r, (p << 1) | 1);
    push_up(p);
}

// 区间更新
void update(int l, int r, int c, int s, int t, int p)
{
    if (l <= s && t <= r) {
        d[p] += (t - s + 1) * c;
        b[p] += c;
        return;
    }
    push_down(s, t, p);
    int m = s + ((t - s) >> 1);
    if (l <= m)
        update(l, r, c, s, m, p << 1);
    if (r > m)
        update(l, r, c, m + 1, t, (p << 1) | 1);
    push_up(p);
}

// 区间查询
int getsum(int l, int r, int s, int t, int p)
{
    if (l <= s && t <= r)
        return d[p];
    push_down(s, t, p);
    int m = s + ((t - s) >> 1);
    int sum = 0;
    if (l <= m)
        sum = getsum(l, r, s, m, p << 1);
    if (r > m)
        sum += getsum(l, r, m + 1, t, (p << 1) | 1);
    return sum;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    // 初始化线段树
    memset(d, 0, sizeof(d));
    memset(b, 0, sizeof(b));
    build(1, n, 1);

    for (int i = 1; i <= m; i++) {
        int op, x, y, k;
        cin >> op;
        if (op == 1) {
            cin >> x >> y >> k;
            update(x, y, k, 1, n, 1);
        } else {
            cin >> x >> y;
            cout << getsum(x, y, 1, n, 1) << '\n';
        }
    }

    return 0;
}